package com.tmt.datatable.editor.instance.impl;

import com.tmt.datatable.editor.instance.INewInstance;
import com.tmt.helper.ReflectHelper;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Created by ThreeManTeam on 2017/6/5.
 */
public class ListInstancer implements INewInstance {

    @Override
    public  boolean support(Class clazz) {
        return clazz.isAssignableFrom(List.class) || clazz.isArray();
    }

    @Override
    public <T> Object newInstance(T object, String fieldName, Map<String, Object> newRootPropObjectMap){
        Object propObj = null;
        try {
            String curProp = fieldName.split("\\[")[0];
            Class clazz = ReflectHelper.getFieldClassByFieldName(object.getClass(), curProp);
            propObj = ReflectHelper.getFieldValue(object, curProp);
            if (propObj == null) {
                propObj = new LinkedList<>();
                ReflectHelper.setFieldValue(object, curProp, propObj);

                if (newRootPropObjectMap != null && newRootPropObjectMap.isEmpty())
                    newRootPropObjectMap.put(curProp, object);
            }

            if (List.class.isAssignableFrom(clazz) && fieldName.contains("[")) {
                String strIndex = fieldName.split("\\[")[1].replaceAll("\\]", "");
                int index = 0;
                try {
                    index = Integer.parseInt(strIndex);
                } catch (Exception ex) {
                }

                Class itemClazz = ReflectHelper.getActualClassByFieldName(object.getClass(), curProp);
                Object itemObject = propObj;
                List list = ((List) propObj);
                for (int i = 0; i <= index; i++) {
                    if (i < list.size()) {
                        itemObject = list.get(i);
                        continue;
                    }
                    itemObject = itemClazz.newInstance();
                    list.add(itemObject);
                }
                propObj = itemObject;
            }

        }catch (Exception ex){
            ex.printStackTrace();
        }

        return propObj;
    }
}
